package com.eddie.juc.cf;

import com.eddie.juc.IThreadPool;
import lombok.SneakyThrows;

import java.util.concurrent.CompletableFuture;
import java.util.concurrent.TimeUnit;

/**
 * @author Eddie
 * @date 2022/08/18 10:15
 **/
public class CompletableFutureApi2Demo {

    private static final IThreadPool threadPool = IThreadPool.getInstance();

    @SneakyThrows
    public static void main(String[] args) {
        //第一步
        CompletableFuture<Integer> completableFuture = CompletableFuture.supplyAsync(() -> {
            try {
                TimeUnit.SECONDS.sleep(1);
            } catch (InterruptedException e) {
                throw new RuntimeException(e);
            }
            System.out.println(Thread.currentThread().isDaemon());
            System.out.println("111");
            return 1;
            //第二步,这里改为handle，进行异常捕获，顺便测试这个方法
        }, threadPool).handle((f, throwable) -> {
            //如果为thenApply出现异常不会执行后面
            //如果为handle出现异常继续执行，并且可以捕获异常
//            int i = 10 / 0;
            System.out.println("222");
            return f + 2;
            //第三步,也设置为handle，进行异常捕获
        }).handle((f, e) -> {
            System.out.println("333");
            return f + 3;
            //完成时,返回最后一步的结果，如果有异常也会返回异常
        }).whenComplete((v, e) -> {
            //判断是否有异常
            if (e == null) {
                System.out.println("==计算结果==：" + v);
            }
            //有异常时,捕获异常
        }).exceptionally(e -> {
            e.printStackTrace();
            System.out.println(e.getMessage());
            return null;
        });
        System.out.println(Thread.currentThread().getName() + "---忙其他任务");
        //CompletableFuture默认使用ForkJoinPool公共线程池，而这个线程池默认提供守护线程
        //解决守护线程在用户线程结束之后自动结束的办法
        //一、让主线程多休眠一会儿，等待守护线程执行完毕
//        TimeUnit.SECONDS.sleep(2);
        //二、使用自定义
        threadPool.shutdown();
    }
}
